#include "database.h"
#include <QDebug>
#include <QFile>

database::database() : db(nullptr), isOpen(false) {
    if (!openDatabase()) {
        qDebug() << "Failed to open database";
    }
}

database::~database() {
    closeDatabase();
}

bool database::openDatabase() {
    if (isOpen) return true;

    if (!QFile::exists("englishwords.db")) {
        qDebug() << "Database file englishwords.db not found";
        return false;
    }

    int rc = sqlite3_open("englishwords.db", &db);
    if (rc != SQLITE_OK) {
        qDebug() << "Can't open database:" << sqlite3_errmsg(db);
        return false;
    }

    isOpen = true;
    return true;
}

void database::closeDatabase() {
    if (db) {
        sqlite3_close(db);
        db = nullptr;
    }
    isOpen = false;
}

WordResult database::searchWord(const QString& word) {
    WordResult result;

    if (!isOpen) return result;

    sqlite3_stmt* stmt;
    const char* sql = "SELECT word, pronunciation, meaning FROM englishwords WHERE word = ? LIMIT 1";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        qDebug() << "Failed to prepare statement:" << sqlite3_errmsg(db);
        return result;
    }

    QByteArray wordBytes = word.toUtf8();
    sqlite3_bind_text(stmt, 1, wordBytes.constData(), wordBytes.length(), SQLITE_TRANSIENT);

    if (sqlite3_step(stmt) == SQLITE_ROW) {
        result.word = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
        result.pronunciation = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)));
        result.meaning = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2)));
    }

    sqlite3_finalize(stmt);
    return result;
}

QVector<QString> database::searchByPrefix(const QString& prefix, int limit) {
    QVector<QString> suggestions;

    if (!isOpen) return suggestions;

    sqlite3_stmt* stmt;
    const char* sql = "SELECT word FROM englishwords WHERE word LIKE ? || '%' ORDER BY word LIMIT ?";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        qDebug() << "Failed to prepare statement:" << sqlite3_errmsg(db);
        return suggestions;
    }

    QByteArray prefixBytes = prefix.toUtf8();
    sqlite3_bind_text(stmt, 1, prefixBytes.constData(), prefixBytes.length(), SQLITE_TRANSIENT);
    sqlite3_bind_int(stmt, 2, limit);

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        QString word = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
        suggestions.append(word);
    }

    if (rc != SQLITE_DONE) {
        qDebug() << "Error executing query:" << sqlite3_errmsg(db);
    }

    sqlite3_finalize(stmt);
    return suggestions;
}

QVector<QString> database::getNext20Words(const QString& prefix) {
    QVector<QString> words;

    if (!isOpen) return words;

    sqlite3_stmt* stmt;
    const char* sql = "SELECT word FROM englishwords WHERE word >= ? ORDER BY word LIMIT 20";

    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        qDebug() << "Failed to prepare statement:" << sqlite3_errmsg(db);
        return words;
    }

    QByteArray prefixBytes = prefix.toUtf8();
    sqlite3_bind_text(stmt, 1, prefixBytes.constData(), prefixBytes.length(), SQLITE_TRANSIENT);

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        QString word = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
        words.append(word);
    }

    if (rc != SQLITE_DONE) {
        qDebug() << "Error executing query:" << sqlite3_errmsg(db);
    }

    sqlite3_finalize(stmt);
    return words;
}
